package com.baaio.conn;

import static com.baaio.util.Out.print;

import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import com.baaio.conn.Interface.BaaioConn;
import com.baaio.reflect.BaaioReflect;
import com.baaio.util.GetInfo;
import com.baaio.util.Out;

public class BaaioConnBase implements BaaioConn {

	private static Statement dbstate = null;
	private static ResultSet dbresult = null;
	private GetSqlString gss;

	protected BaaioConnBase() {
		GetStatement gs = new GetStatement(GetInfo.getInstance().getDb());
		dbstate = gs.getStatement();
		gss = new GetSqlString();
	}

	protected BaaioConnBase(String dbname) {
		GetStatement gs = new GetStatement(dbname);
		gss = new GetSqlString();
		dbstate = gs.getStatement();
	}

	@Override
	public ResultSet queryData(String tableName, ArrayList<String> list,
			String condiction) {

		return select(gss.dbSelect(tableName, list, condiction));
	}

	@Override
	public ResultSet queryData(String tableName, String fields,
			String condiction) {

		return select(gss.dbSelect(tableName, fields, condiction));
	}

	@Override
	public boolean saveData(String table, HashMap<String, String> map) {

		return update(gss.dbInsert(table, map));

	}

	@Override
	public boolean saveData(Object object) {

		BaaioReflect br = new BaaioReflect();
		return saveData(br.getTableName(object), br.getValue(object));

	}

	@Override
	public boolean removeData(String tableName, String condition) {

		return delete(gss.dbDelete(tableName, condition));

	}

	@Override
	public boolean removeData(String tableName, String cName,
			ArrayList<String> list) {

		boolean f = false;
		for (String sql2 : list) {
			f = removeData(tableName, cName, sql2);

		}
		return f;
	}

	@Override
	public boolean removeData(String tableName, String dcName, String condiction) {

		return delete(gss.dbDelete(tableName, dcName, condiction));

	}

	@Override
	public boolean updateData(String tabName, HashMap<String, String> map,
			String upCondition) {

		return update(gss.dbUpdate(tabName, map, upCondition));

	}

	@Override
	public boolean updateData(Object object, Object upConditionObject) {

		BaaioReflect br = new BaaioReflect();
		return update(gss
				.dbUpdate(br.getTableName(object), br.getValue(object),
						br.getUpConditionString(upConditionObject)));

	}

	@Override
	public ResultSet query(String sql) {

		try {
			print("Sql = " + sql);
			dbresult = dbstate.executeQuery(sql);

		} catch (SQLException e) {
			e.printStackTrace();

		}

		return dbresult;
	}

	@Override
	public void close() {

		GetStatement.dbClose();

	}

	private ResultSet select(String sql) {

		try {

			try {
				dbresult = dbstate.executeQuery(sql);
				print("Sql = " + sql);

			} catch (Exception err) {
				print("Sql = " + sql);
				print("Exception: " + err.getMessage());
			}

		} catch (Exception e) {
			print("Exception: " + e.getMessage());
		}

		return dbresult;
	}

	private boolean update(String sql) {

		boolean updateResult = false;
		try {
			dbstate.executeUpdate(sql);
			print("sql = " + sql);
			updateResult = true;
		} catch (Exception err) {
			print("sql = " + sql);
			print("Exception: " + err.getMessage());
		}
		if (updateResult)
			return true;
		else
			return false;
	}

	private boolean delete(String sql) {

		boolean delResult = false;
		try {
			print("Sql = " + sql);
			dbstate.executeUpdate(sql); // return int // int delRe = ??
			delResult = true;
		} catch (Exception e) {
			print("sql = " + sql);
			print("Exception: " + e.getMessage());
		}
		return delResult;
	}

	@Override
	public boolean clearTableTruncate(String tableName) {
		// TODO Auto-generated method stub

		return delete(gss.dbDelete(tableName));
	}

	@Override
	public boolean removeData(Object object, String value) {

		BaaioReflect brf = new BaaioReflect();
		String key = brf.getKeyValue(object).get("key");

		HashMap<String, String> map = brf.getOneToMany(object);
		String tableName = brf.getTableName(object);
		String itemValue2 = null;
		ResultSet rs = query(gss.dbSelect(tableName, map.get("baaioKey"), key,
				value));

		try {
			while (rs.next()) {
				itemValue2 = rs.getString(1);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		Set<String> set = map.keySet();
		for (Iterator<String> i = set.iterator(); i.hasNext();) {
			String tableName2 = i.next();
			String itemValue = map.get(tableName2);
			if (!tableName2.equals("baaioKey"))
				delete(gss.dbDelete(tableName2, itemValue, itemValue2));

		}

		return delete(gss.dbDelete(tableName, key, value));

	}

	@Override
	public ResultSet queryX(String tableName) {

		return query("select * from " + tableName);
	}

	@Override
	public ResultSet queryData(Object object, String value) {

		BaaioReflect brf = new BaaioReflect();
		String key = brf.getKeyValue(object).get("baaio-key");
		String tableName = brf.getTableName(object);
		return query(gss.dbSelect(tableName, key, value));
	}

	@Override
	public ResultSet lift(Object A, Object B) {

		BaaioReflect br = new BaaioReflect();
		String Akey = br.getKeyValue(A).get("baaio-key");
		String Bkey = br.getKeyValue(B).get("baaio-key");

		String AT = br.getTableName(A);
		String BT = br.getTableName(B);
		String sql = "select * from " + AT + " left join " + BT + " on " + Akey
				+ "=" + Bkey;

		return query(sql);

	}

	@Override
	public boolean hasData(String tableName, String item, String value) {

		ResultSet rs = query(gss.dbSelect(tableName, item, value));

		try {
			return rs.next();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public Object queryDataB(Object object, String value) {
		// TODO Auto-generated method stub
		ResultSet rs = queryData(object, value);
		try {
			rs.next();
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		GetAllListData gat = new GetAllListData();
		// ArrayList<HashMap<String, String>> list2 = gat.getSelect(object,
		// value);
		String tbname = new BaaioReflect().getTableName(object);
		Method[] md = object.getClass().getMethods();
		try {
			ArrayList<String> list = gat.getColumnName(tbname);

			for (String str : list) {
				String mdName = "set" + str.substring(0, 1).toUpperCase()
						+ str.substring(1);
				for (int i = 0; i < md.length; i++) {
					if (md[i].getName().equals(mdName)) {
						md[i].invoke(object, rs.getString(str));
					}
				}

			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return object;
	}

	@Override
	public Object queryDataA(Object object) {
		// TODO Auto-generated method stub
		BaaioReflect brf = new BaaioReflect();
		String tbname = brf.getTableName(object);
		GetAllListData gat = new GetAllListData();
		ArrayList<String> list = null;
		try {
			list = gat.getColumnName(tbname);
		} catch (Exception e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		ResultSet rs = getRs(object, list);
		try {
			rs.next();
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// ArrayList<HashMap<String, String>> list2 = gat.getSelect(object,
		// value);
		Method[] md = object.getClass().getMethods();
		try {

			for (String str : list) {
				String mdName = "set" + str.substring(0, 1).toUpperCase()
						+ str.substring(1);
				for (int i = 0; i < md.length; i++) {
					if (md[i].getName().equals(mdName)) {
						md[i].invoke(object, rs.getString(str));
					}
				}

			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return object;
	}

	@Override
	public boolean hasData(Object object) {
	    BaaioReflect brf = new BaaioReflect();
	    String tbname = brf.getTableName(object);
	    GetAllListData gat = new GetAllListData();
	    ArrayList<String> list = null;
	    try {
	      list = gat.getColumnName(tbname);
	    }
	    catch (Exception e2) {
	      e2.printStackTrace();
	    }
	    ResultSet rs = getRs(object, list);
	    try
	    {
	      return rs.next();
	    }
	    catch (SQLException e) {
	      e.printStackTrace();
	    }return false;
	}

	private ResultSet getRs(Object object, ArrayList<String> list) {
		BaaioReflect brf = new BaaioReflect();
		ArrayList<String> fields = new ArrayList<String>();
		StringBuffer buffer = new StringBuffer();
		HashMap<String, String> map = brf.getKeyAllValue(object, list);
		Out.print("baaio:      " + map.toString());
		Set<String> set = map.keySet();
		int size = set.size();
		System.out.println(size);
		int ii = 1;
		buffer.append("where ");
		for (Iterator<String> i = set.iterator(); i.hasNext();ii++) {
			String key = i.next();
			if (!key.equals("baaio-key")) {
				String value = map.get(key);
				buffer.append(key.substring(3).toLowerCase() + " = '" + value + "' ");
				
				if (size > ii) {
					buffer.append("and ");
				}
			}
		}

		String tbname = brf.getTableName(object);

		ResultSet rs = query(gss.dbSelect(tbname, fields, buffer.toString()));
		return rs;
	}

}
